using Eno.Application.Services;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using System.Diagnostics;

namespace Eno.Infrastructure.Middleware;

public class RequestLoggingMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ILogger<RequestLoggingMiddleware> _logger;

    public RequestLoggingMiddleware(RequestDelegate next, ILogger<RequestLoggingMiddleware> logger)
    {
        _next = next;
        _logger = logger;
    }

    public async Task InvokeAsync(HttpContext context, ILogService logService)
    {
        var stopwatch = Stopwatch.StartNew();
        var originalBodyStream = context.Response.Body;

        try
        {
            // 记录请求开始
            var requestInfo = new
            {
                context.Request.Method,
                context.Request.Path,
                QueryString = context.Request.QueryString.ToString(),
                UserAgent = context.Request.Headers["User-Agent"].ToString(),
                IpAddress = context.Connection.RemoteIpAddress?.ToString(),
                UserId = context.User?.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value,
                UserName = context.User?.FindFirst(System.Security.Claims.ClaimTypes.Name)?.Value
            };

            //! 数据库Message请求数据
            await logService.LogInfoAsync(
                $"HTTP {context.Request.Method} {context.Request.Path}",
                "RequestLogging",
                requestInfo
            );

            // 继续处理请求
            await _next(context);

            stopwatch.Stop();

            // 记录响应信息
            var responseInfo = new
            {
                context.Response.StatusCode,
                Duration = stopwatch.ElapsedMilliseconds,
                context.Response.ContentType
            };
           //! 数据中Message响应数据
            await logService.LogInfoAsync(
                $"HTTP {context.Request.Method} {context.Request.Path} completed with status {context.Response.StatusCode}",
                "RequestLogging",
                responseInfo
            );
        }
        catch (Exception ex)
        {
            stopwatch.Stop();

            // 记录异常
            await logService.LogErrorAsync(
                $"HTTP {context.Request.Method} {context.Request.Path} failed",
                ex,
                "RequestLogging",
                new
                {
                    Duration = stopwatch.ElapsedMilliseconds,
                    Exception = ex.Message
                }
            );

            throw;
        }
    }
}